home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / jpl_c.zip / ALLOT.C < prev    next >
Text File  |  1986-05-18  |  4KB  |  115 lines

  1. /* 1.3  02-11-86                         (allot.c)
  2.  ************************************************************************
  3.  *            Robert C. Tausworthe                *
  4.  *            Jet Propulsion Laboratory            *
  5.  *            Pasadena, CA 91009        1985, 86    *
  6.  ************************************************************************/
  7.  
  8. #include "defs.h"
  9. #include "stdtyp.h"
  10.  
  11. /*----------------------------------------------------------------------*/
  12.  
  13. LOCAL HEADER base;         /* empty list to get started.        */
  14. LOCAL HEADER *allocp = NULL;    /* last allocated block.        */
  15.  
  16. /************************************************************************/
  17.     char *
  18. allot(nbytes)        /* Return pointer to block of memory nbytes in
  19.                size, or NULL if none available.        */
  20. /*----------------------------------------------------------------------*/
  21. unsigned nbytes;
  22. {
  23.     HEADER *morecore();    /* Almost straight out of K & R.    */
  24.     FAST HEADER *p, *q;
  25.     FAST unsigned ru, au;    /* requested units, allotted units.    */
  26.     unsigned n_units();
  27.  
  28.     if ((q = allocp) IS NULL)
  29.     {    base.s.ptr = allocp = q = &base;
  30.         base.s.size = 0;
  31.     }
  32.     ru = n_units(nbytes);        /* convert to units    */
  33.     for (p = q->s.ptr; ; q = p, p = p->s.ptr)
  34.     {    if (p->s.size >= nbytes)
  35.         {    if ((au = n_units(p->s.size)) > ru)
  36.             {    p->s.size = (au -= ru) * sizeof(HEADER);
  37.                  p += au;
  38.             }
  39.             else        /* allot the whole block.    */
  40.                 q->s.ptr = p->s.ptr;
  41.             allocp = q;
  42.             return (char *) p;
  43.         }
  44.         if ((p IS allocp) AND NOT(p = morecore(ru)))
  45.             return NULL; /* wrapped around free list and
  46.                     no memory left.            */
  47.     }
  48. }
  49. /*\p*********************************************************************/
  50.     VOID
  51. liberate(ap, nbytes)    /* Put block of nbytes pointed to by ap into the
  52.                available list.                */
  53. /*----------------------------------------------------------------------*/
  54. char *ap;
  55. unsigned nbytes;
  56. {
  57.     FAST HEADER *p, *q;
  58.     unsigned n_units();
  59.  
  60.     if (NOT p)
  61.         return;
  62.  
  63.     p = (HEADER *) ap;            /* point to header    */
  64.     for (q = allocp; NOT(q < p AND p < q->s.ptr); q = q->s.ptr)
  65.         if (q >= q->s.ptr AND (q < p OR p < q->s.ptr))
  66.             break;           /* stop if at one end or another    */
  67.  
  68.     p->s.size = nbytes;            /* record the size    */
  69.     if ((p + n_units(p->s.size)) IS q->s.ptr /* join to upper nghbor?*/
  70.        AND (nbytes % sizeof(HEADER)) IS 0)    /* only if no holes.    */
  71.     {    p->s.size += q->s.ptr->s.size;
  72.         p->s.ptr = q->s.ptr->s.ptr;
  73.     }
  74.     else
  75.         p->s.ptr = q->s.ptr;
  76.     if (q + n_units(q->s.size) IS p)    /* join to lower nbr? */
  77.     {    q->s.size += p->s.size;
  78.         q->s.ptr = p->s.ptr;
  79.     }
  80.     else
  81.         q->s.ptr = p;
  82.     allocp = q;
  83. }
  84. /*\p*********************************************************************/
  85.     LOCAL HEADER *
  86. morecore(nu)        /* ask system for nu blocks of memory and put on
  87.                the available list. Return ptr to the block. */
  88. /*----------------------------------------------------------------------*/
  89. unsigned nu;
  90. {
  91.     char *sbrk();
  92.     FAST char *cp;
  93.     FAST HEADER *up;
  94.     FAST unsigned rnu;
  95.  
  96.     rnu = NALLOC * ((nu + NALLOC - 1) / NALLOC);
  97.     cp = sbrk(nu = rnu * sizeof(HEADER));    /* nu now no. of bytes    */
  98.     if ((int) cp IS EOF)            /* no space at all    */
  99.         return NULL;
  100.  
  101.     up = (HEADER *) cp;
  102.     liberate((char *) up, nu);
  103.     return allocp;
  104. }
  105.  
  106. /************************************************************************/
  107.     unsigned
  108. n_units(n)        /* return the number of HEADER-sized units
  109.                required to cover n bytes.            */
  110. /*----------------------------------------------------------------------*/
  111. unsigned n;
  112. {
  113.     return (n + sizeof(HEADER) - 1) / sizeof(HEADER);
  114. }
  115.